package com.xinyi.httpdemo.config;

import com.xinyi.httpdemo.server.IRequestServer;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;

/**
 * @author 杨耿雷
 * @date 2024/9/24 10:59
 * @description okhttp网络请求配置类【简单示例】
 */
public final class OkHttpConfig {

    private static volatile OkHttpConfig sConfig;

    /**
     * 服务器配置
     */
    private IRequestServer mServer;

    /**
     * OkHttp 客户端
     */
    private OkHttpClient mClient;

    /**
     * 请求拦截器
     */
    private IRequestInterceptor mInterceptor;

    /**
     * 全局请求参数
     */
    private HashMap<String, Object> mParams;

    /**
     * 全局请求请求头
     */
    private HashMap<String, String> mHeaders;

    /**
     * 重试次数
     */
    private int mRetryCount = 1;

    /**
     * 重试时间
     */
    private long mRetryTime = 2000;

    private OkHttpConfig(OkHttpClient client) {
        mClient = client;
        mParams = new HashMap<>();
        mHeaders = new HashMap<>();
    }

    /**
     * 获取配置实例
     */
    public static OkHttpConfig getInstance() {
        if (sConfig == null) {
            // 当前没有初始化配置
            throw new IllegalStateException("You haven't initialized the configuration yet");
        }
        return sConfig;
    }

    /**
     * 设置配置实例
     */
    private static void setInstance(OkHttpConfig config) {
        sConfig = config;
    }

    /**
     * 创建配置实例
     */
    public static OkHttpConfig with() {
        return new OkHttpConfig(new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)  // 连接超时
                .readTimeout(30, TimeUnit.SECONDS)  // 读取超时
                .writeTimeout(15, TimeUnit.SECONDS)  // 写入超时
                .build()
        );
    }

    /**
     * 设置服务器配置
     */
    public OkHttpConfig setServer(IRequestServer server) {
        mServer = server;
        return this;
    }

    /**
     * 设置OkHttp客户端
     */
    public OkHttpConfig setClient(OkHttpClient client) {
        mClient = client;
        if (mClient == null) {
            throw new IllegalArgumentException("The OkHttp client object cannot be empty");
        }
        return this;
    }

    /**
     * 设置请求拦截器
     */
    public OkHttpConfig setInterceptor(IRequestInterceptor interceptor) {
        mInterceptor = interceptor;
        return this;
    }

    /**
     * 设置全局请求参数
     */
    public OkHttpConfig setParams(HashMap<String, Object> params) {
        if (params == null) {
            params = new HashMap<>();
        }
        mParams = params;
        return this;
    }

    /**
     * 设置全局请求头
     */
    public OkHttpConfig setHeaders(HashMap<String, String> headers) {
        if (headers == null) {
            headers = new HashMap<>();
        }
        mHeaders = headers;
        return this;
    }

    /**
     * 添加全局请求头
     */
    public OkHttpConfig addHeader(String key, String value) {
        if (key != null && value != null) {
            mHeaders.put(key, value);
        }
        return this;
    }

    /**
     * 移除全局请求头
     */
    public OkHttpConfig removeHeader(String key) {
        if (key != null) {
            mHeaders.remove(key);
        }
        return this;
    }

    /**
     * 添加全局请求参数
     */
    public OkHttpConfig addParam(String key, String value) {
        if (key != null && value != null) {
            mParams.put(key, value);
        }
        return this;
    }

    /**
     * 移除全局请求参数
     */
    public OkHttpConfig removeParam(String key) {
        if (key != null) {
            mParams.remove(key);
        }
        return this;
    }

    /**
     * 设置重试次数
     */
    public OkHttpConfig setRetryCount(int count) {
        if (count < 0) {
            // 重试次数必须大于等于 0 次
            throw new IllegalArgumentException("The number of retries must be greater than 0");
        }
        mRetryCount = count;
        return this;
    }

    /**
     * 设置重试时间
     */
    public OkHttpConfig setRetryTime(long time) {
        if (time < 0) {
            // 重试时间必须大于等于 0 毫秒
            throw new IllegalArgumentException("The retry time must be greater than 0");
        }
        mRetryTime = time;
        return this;
    }

    /**
     * 获取服务器配置
     */
    public IRequestServer getServer() {
        return mServer;
    }

    /**
     * 获取OkHttp客户端
     */
    public OkHttpClient getClient() {
        return mClient;
    }

    /**
     * 获取请求拦截器
     */
    public IRequestInterceptor getInterceptor() {
        return mInterceptor;
    }

    /**
     * 获取全局请求参数
     */
    public HashMap<String, Object> getParams() {
        return mParams;
    }

    /**
     * 获取全局请求头
     */
    public HashMap<String, String> getHeaders() {
        return mHeaders;
    }

    /**
     * 获取重试次数
     */
    public int getRetryCount() {
        return mRetryCount;
    }

    /**
     * 获取重试时间
     */
    public long getRetryTime() {
        return mRetryTime;
    }

    /**
     * 初始化配置
     */
    public void init() {
        if (mClient == null) {
            throw new IllegalArgumentException("Please set up the OkHttpClient object");
        }
        if (mServer == null) {
            throw new IllegalArgumentException("Please set up the RequestServer object");
        }
        try {
            // 校验主机和路径的 url 是否合法
            new URL(mServer.getHost());
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("The configured host path url address is not correct");
        }
        OkHttpConfig.setInstance(this);
    }
}